package org.orbis.search;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.CountDownLatch;

import org.orbis.communicate.FlagsResult;
import org.orbis.communicate.hash.Hashing;
import org.orbis.structure.ContentInfo;
import org.orbis.term.Term;
import org.orbis.term.TermList;

public class SearchResultPackage implements Iterable<SearchResult>{
	private SearchPackage query;
	private TermList terms;
	private int searchCount;
	private CountDownLatch latch;
	private FlagsResult[][] result;
	private boolean isNotFound;
	private ArrayList<SearchResult> finalResult;

	private SearchResultPackage(){}

	public static SearchResultPackage make(TermList terms, ContentInfo contentInfo, SearchPackage query, int maxSearcher){
		SearchResultPackage pkg = new SearchResultPackage();

		pkg.query = query;
		pkg.terms = terms;
		int maxResult = terms.size() > maxSearcher? maxSearcher: terms.size();
		pkg.searchCount = maxResult;
		pkg.latch = new CountDownLatch(maxResult);
		pkg.result = new FlagsResult[maxResult][];
		pkg.isNotFound = false;
		pkg.finalResult = new ArrayList<SearchResult>(100);

		return pkg;
	}
	
	public SearchPackage query() {
		return query;
	}

	public void setResult(SearchResult result, int rank){
		result.setIndex(rank + 1);
		this.finalResult.add(result);
	}

	public SearchResult[] getResults(){
		return finalResult.toArray(new SearchResult[0]);
	}
	
	public int from() {
		return query.from();
	}
	
	public void setCount(int count) {
		searchCount = count;
	}
	
	public int count() {
		return searchCount;
	}
	
	public int total() {
		return query.length();
	}
	
	public int length() {
		return finalResult.size();
	}

//	public int getArraySize() {
//		return (contentInfo.contentsNum() + contentInfo.appendixNum()) * results.size();
//	}

	public long getTermHash(int index){
		return Hashing.getTermHash(terms.get(index).str());
	}

	public int getCount(){
//		return terms.size();
		return searchCount;
	}

	public Term getTerm(int index){
		return terms.get(index);
	}

	public FlagsResult[][] getAllResult(){
		return result;
	}

	public FlagsResult[] getResult(int index){
		if(index >= result.length) return null;
		return result[index];
	}

	public void setResult(int index, FlagsResult[] invIndices){
		result[index] = invIndices;
	}

	public void notFound(){
		isNotFound = true;
	}

	public boolean isNotFound(){
		return isNotFound;
	}

	public void countdown(){
		latch.countDown();
	}

	public void waitLatch(){
		try{
			latch.await();
		}catch(InterruptedException e){}
	}
	
	@Override
	public Iterator<SearchResult> iterator(){
		return finalResult.iterator();
	}
}
